<%@ page contentType="text/html; charset=utf-8" %>
<%@ taglib prefix="tiles" uri="http://struts.apache.org/tags-tiles"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="c_rt" uri="http://java.sun.com/jstl/core_rt"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@ taglib prefix="fmt_rt" uri="http://java.sun.com/jstl/fmt_rt"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql"%>
<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml"%>
<%@ taglib prefix="x_rt" uri="http://java.sun.com/jstl/xml_rt"%>
<%@ taglib prefix="wr_fn" uri="http://njo.org/taglib/functions"%>
<%@page import="java.io.*" %>
<%@page import="java.util.*" %>
<%@page import="org.apache.commons.fileupload.*" %>
<%@page import="org.njo.webapp.root.utility.SystemContext" %>

<%
  String ROOT_PATH = SystemContext.getProperty("download.realpath","/opt");
%>
<%
  String APACHE_DOWNLOAD_PATH = SystemContext.getProperty("download.path","download");
  String FILE_SEPARATOR = "/";

  int M = 1024 * 1024;
  int K = 1024;

  // 请求的路径
  String requestPath = "";
  // 相对路径
  String relativelyPath = "";
  // 取得本地真实的路径
  String realPath = "";
  // 操作标记
  String action = "";

  // 取得游览器输入
  Map input = parseRequest(request);
  System.out.println("input=" + input);

  // 取得操作标记
  action = getString(input.get("action"), "showdir");
  requestPath = getString(input.get("requestPath"));
  relativelyPath = getString(input.get("relativelyPath"));
  // TODO: 出于安全考虑需要check[requestPath]和[relativelyPath]这两个目录合法

  if ("upload".equals(action)) {            // 上传文件
    realPath = ROOT_PATH + relativelyPath;
    FileItem fileItem = (FileItem)input.get("theFile");
    retrieveFileToDisk(fileItem, realPath);
  } else if ("showdir".equals(action)) {   // 显示目录
    // 算出请求的路径
    relativelyPath = relativelyPath + requestPath + FILE_SEPARATOR;
    realPath = ROOT_PATH + relativelyPath;
  } else if ("cd..".equals(action)) {      // 显示上一层目录
    // 取得父目录路径
    int pos = relativelyPath.lastIndexOf(FILE_SEPARATOR);
    relativelyPath = relativelyPath.substring(0,pos);
    pos = relativelyPath.lastIndexOf(FILE_SEPARATOR, pos);
    relativelyPath = relativelyPath.substring(0,pos+1);
    realPath = ROOT_PATH + relativelyPath;
  } else if ("createdir".equals(action)) { // 创建目录
    // TODO:check folder name
    String folder = getString(input.get("folder"));

    realPath = ROOT_PATH + relativelyPath;
    File folderFile = new File(realPath, folder);
    folderFile.mkdir();
    
  } else if ("delete".equals(action)) { // 创建目录


  }

  request.setAttribute("relativelyPath", relativelyPath);
  request.setAttribute("requestPath", requestPath);
  request.setAttribute("relativelyPath", relativelyPath);
  request.setAttribute("realPath", realPath);

  System.out.println("path=" + realPath);
%>
<script type="text/javascript">
<!--

  function showdir(path) {
    document.f1.action.value = 'showdir';
    document.f1.requestPath.value = path;
    document.f1.submit();
  }

  function showparentdir() {
    document.f1.action.value = 'cd..';
    document.f1.submit();
  }

  function upload() {

  }

  function createdir() {

  }

  function deletefile() {

  }

-->
</script>

<c:if test="${wr_fn:isUserInRole(pageContext.request, 'admin')}">
  <table class="forum" width="98%">
  <col width="*"/>
  <tbody>
    <tr class="even">
      <form name="f3" action="${pageContext.request.contextPath}/download.tiles" method="post">
        <input type="hidden" name="action" value="createdir"/>
        <input type="hidden" name="requestPath" value=""/>
        <input type="hidden" name="relativelyPath" value="${relativelyPath}"/>
        <td>Create Folder: <input name="folder"/> <input name="btn1" type="submit" value="OK"/></td>
      </form>
    </tr>
    <tr class="even">
      <form name="f2" action="${pageContext.request.contextPath}/download.tiles" enctype="multipart/form-data" method="post">
        <input type="hidden" name="action" value="upload"/>
        <input type="hidden" name="requestPath" value=""/>
        <input type="hidden" name="relativelyPath" value="${relativelyPath}"/>
        <td>Upload File: <input type="file" name="theFile"/> <input name="btn2" type="submit" value="OK"/></td>
      </form>
    </tr>
  </tbody>
  </table>
</c:if>

<form name="f1" action="${pageContext.request.contextPath}/download.tiles" method="post">
  <input type="hidden" name="action" value="showdir"/>
  <input type="hidden" name="requestPath" value=""/>
  <input type="hidden" name="relativelyPath" value="${relativelyPath}"/>
  <h3><a name="welcome">${relativelyPath}</a></h3>
  <table class="forum" width="98%">
  <col width="*"/>
  <col width="150"/>
  <col width="120"/>
  <tbody>
  <tr>
    <th>Name</th>
    <th>Last modified</th>
    <th>Size</th>
  </tr>
<% if (!FILE_SEPARATOR.equals(relativelyPath)) {%>
      <tr>
        <td class="even" colspan="3">[<a href="javascript:showparentdir();">...</a>]</td>
      </tr>
<% }%>
<%
  File realDirFile = new File(realPath);
  File[] filesList = realDirFile.listFiles();

  Comparator c = new Comparator() {
      public int compare(Object o1, Object o2) {
        String n1 = ((File)o1).getName();
        String n2 = ((File)o2).getName();
        return n1.compareTo(n2);
      }
      public boolean equals(Object obj) {
        return false;
      }
  };
  Arrays.sort(filesList, c);

  java.text.SimpleDateFormat dateFormat = new java.text.SimpleDateFormat("yyyy/MM/dd hh:mm");

  int index = 0;
  %>
<%
  for(int i=0;i<filesList.length;i++) {
    if(!filesList[i].isFile()) {
      index++;
  %>
    <tr class="<%=index%2==1 ? "odd" : "even" %>">
      <td><a href="javascript:showdir('<%=filesList[i].getName()%>');"><%=filesList[i].getName()%>/</a></td>
      <td class="right"><%=dateFormat.format(new Date(filesList[i].lastModified()))%></td>
      <td>&nbsp;</td>
    </tr>
<%  }
  }
  %>

<%for(int i=0;i<filesList.length;i++) {
    if(filesList[i].isFile()) {
      index++;
  %>
    <tr class="<%=index%2==1 ? "odd" : "even" %>">
      <td><a href="<%=APACHE_DOWNLOAD_PATH + relativelyPath + filesList[i].getName()%>"><%=filesList[i].getName()%></a><br></td>
      <td class="right"><%=dateFormat.format(new Date(filesList[i].lastModified()))%></td>
      <td class="right"><%=convertFileSize(filesList[i].length())%></td>
    </tr>
<%  }
  }
  %>
  </tbody>
  </table>
</form>

<%!
  String convertFileSize(long filesize) {
    String strUnit="Bytes";
    String strAfterComma="";
    int intDivisor=1;
    if(filesize>=1024*1024) {
      strUnit = "MB";
      intDivisor=1024*1024;
    } else if(filesize>=1024) {
      strUnit = "KB";
      intDivisor=1024;
    }
    if(intDivisor==1) return filesize + " " + strUnit;
    strAfterComma = "" + 100 * (filesize % intDivisor) / intDivisor ;
    if(strAfterComma=="") strAfterComma=".0";
    return filesize / intDivisor + "." + strAfterComma + " " + strUnit;
  }

  /**
   * 复制文件到指定目录.
   *
   */
  boolean retrieveFileToDisk(FileItem file, String path) {
    //retrieve the file representation
    try {
      String fileName = getFileName(file.getName());
      File toFile = new File(path, fileName);
      //retrieve the file data
      InputStream stream = file.getInputStream();
      //write the file to the file specified
      OutputStream bos = new FileOutputStream(toFile);
      int bytesRead = 0;
      byte[] buffer = new byte[8192];
      while ((bytesRead = stream.read(buffer, 0, 8192)) != -1) {
          bos.write(buffer, 0, bytesRead);
      }
      bos.close();
      stream.close();
      return true;
    } catch (FileNotFoundException fnfe) {
        return false;
    } catch (IOException ioe) {
        return false;
    }
  }

  String getString(Object o) {
    if (o==null) {
      return "";
    }
    if (o instanceof String) {
      return (String)o;
    } else if (o instanceof FileItem) {
      String v = ((FileItem)o).getString();
      if (v==null) return "";
      return v;
    } else {
      return o.toString();
    }
  }

  String getString(Object o, String defaultV) {
    String s = getString(o);
    if ("".equals(s)) {
      return defaultV;
    }
    return s;
  }

  /**
   *
   *
   */
  Map parseRequest(HttpServletRequest request) {
    // 判断是否是文件上传.
    String contentTypeHeader = request.getContentType();
    boolean isMultipart = (contentTypeHeader!=null) && (contentTypeHeader.startsWith("multipart/form-data"));
    // 如果文件上传的情况下
    if (isMultipart) {
      // 分析请求并缓存上传内容.
      return parseMultiRequest(request);
    } else {
      Map input = new HashMap();
      Enumeration enu = request.getParameterNames();
      while (enu.hasMoreElements()) {
        String parameterName = (String)enu.nextElement();
        input.put(parameterName, request.getParameter(parameterName));
      }
      return input;
    }
  }


  /**
   * 处理文件上传.
   *
   * 1,分析请求,返回请求参数Map.
   * 2,将上传的文件会被放到缓存(临时文件)中.
   */
  Map parseMultiRequest(HttpServletRequest request) {
    try {
      Map reqMap = new HashMap();
      DiskFileUpload fu = new DiskFileUpload();
      // 设置允许用户上传文件大小,单位:字节
      fu.setSizeMax(1024 * 1024 * 10);
      // 设置最多只允许在内存中存储的数据,单位:字节
      fu.setSizeThreshold(4096);
      // 设定编码集
      fu.setHeaderEncoding("utf-8");
      // 开始读取上传信息
      List fileItems = fu.parseRequest(request);
      for (int i = 0 ; i < fileItems.size(); i++) {
        FileItem item = (FileItem)fileItems.get(i);
        if (item.isFormField()) {
          reqMap.put(item.getFieldName(), item.getString());
        } else {
          reqMap.put(item.getFieldName(), item);
        }
      }
      return reqMap;
    } catch (FileUploadException e) {
      return null;
    }
  }


  String getFileName(String path) {
    if (path==null) {
      return null;
    }

    StringBuffer sb = new StringBuffer();
    int length = path.length();
    if (endsWithSeparator(path)) {
      length--;
    }
    for (int i=length-1;i>0;i--) {
      char c = path.charAt(i);
      if (isSeparator(c)) {
        break;
      }
      sb.insert(0, c);
    }
    return sb.toString();
  }



  
  char[] FILE_SEPARATOR = {'\\','/'};

  boolean isSeparator(char c) {
    for (int i=0;i<FILE_SEPARATOR.length;i++) {
      if (c==FILE_SEPARATOR[i]) {
        return true;
      }
    }
    return false;
  }

  boolean endsWithSeparator(String path) {
    if (path==null) {
      return false;
    }
    for (int i=0;i<FILE_SEPARATOR.length;i++) {
      if (path.endsWith(String.valueOf(FILE_SEPARATOR[i]))) {
        return true;
      }
    }
    return false;
  }






%>
